package com.knowledgegraph.service;

import com.knowledgegraph.entity.Node;
import com.knowledgegraph.entity.NodeRelation;
import com.knowledgegraph.entity.NodeResource;
import com.knowledgegraph.entity.Resource;
import com.knowledgegraph.repository.NodeRelationRepository;
import com.knowledgegraph.repository.NodeRepository;
import com.knowledgegraph.repository.NodeResourceRepository;
import com.knowledgegraph.repository.ResourceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class KnowledgeGraphService {
    
    @Autowired
    private NodeRepository nodeRepository;
    
    @Autowired
    private NodeRelationRepository nodeRelationRepository;
    
    @Autowired
    private ResourceRepository resourceRepository;
    
    @Autowired
    private NodeResourceRepository nodeResourceRepository;
    
    public Node createNode(Node node) {
        return nodeRepository.save(node);
    }
    
    public Optional<Node> getNodeById(Long id) {
        return nodeRepository.findById(id);
    }
    
    public List<Node> getAllNodes() {
        return nodeRepository.findAll();
    }
    
    public List<Node> getNodesByType(String nodeType) {
        return nodeRepository.findByNodeType(nodeType);
    }
    
    public List<Node> searchNodesByName(String name) {
        return nodeRepository.findByNameContainingIgnoreCase(name);
    }
    
    public Node updateNode(Node node) {
        return nodeRepository.save(node);
    }
    
    public void deleteNode(Long id) {
        nodeRepository.deleteById(id);
    }
    
    public NodeRelation createNodeRelation(NodeRelation relation) {
        return nodeRelationRepository.save(relation);
    }
    
    public List<NodeRelation> getRelationsBySourceNode(Long sourceNodeId) {
        return nodeRelationRepository.findBySourceNodeId(sourceNodeId);
    }
    
    public List<NodeRelation> getRelationsByTargetNode(Long targetNodeId) {
        return nodeRelationRepository.findByTargetNodeId(targetNodeId);
    }
    
    public List<NodeRelation> getAllRelationsForNode(Long nodeId) {
        return nodeRelationRepository.findAllRelationsForNode(nodeId);
    }
    
    public void deleteNodeRelation(Long relationId) {
        nodeRelationRepository.deleteById(relationId);
    }
    
    public Resource createResource(Resource resource) {
        return resourceRepository.save(resource);
    }
    
    public Optional<Resource> getResourceById(Long id) {
        return resourceRepository.findById(id);
    }
    
    public List<Resource> getAllResources() {
        return resourceRepository.findAll();
    }
    
    public List<Resource> getResourcesByType(String resourceType) {
        return resourceRepository.findByResourceType(resourceType);
    }
    
    public List<Resource> searchResourcesByName(String name) {
        return resourceRepository.findByNameContainingIgnoreCase(name);
    }
    
    public Resource updateResource(Resource resource) {
        return resourceRepository.save(resource);
    }
    
    public void deleteResource(Long id) {
        resourceRepository.deleteById(id);
    }
    
    public NodeResource createNodeResourceRelation(NodeResource nodeResource) {
        return nodeResourceRepository.save(nodeResource);
    }
    
    public List<NodeResource> getNodeResourceRelationsByNode(Long nodeId) {
        return nodeResourceRepository.findByNodeId(nodeId);
    }
    
    public List<NodeResource> getNodeResourceRelationsByResource(Long resourceId) {
        return nodeResourceRepository.findByResourceId(resourceId);
    }
    
    public void deleteNodeResourceRelation(Long relationId) {
        nodeResourceRepository.deleteById(relationId);
    }
    
    public List<Node> getConnectedNodes(Long nodeId) {
        return nodeRepository.findConnectedNodes(nodeId);
    }
    
    public List<Resource> getResourcesByNode(Long nodeId) {
        return resourceRepository.findResourcesByNodeId(nodeId);
    }
    
    public List<Node> getNodesByResource(Long resourceId) {
        return nodeRepository.findNodesByResourceId(resourceId);
    }
}